package com.info.zhiduoduo.admin.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.baomidou.mybatisplus.mapper.Condition;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Maps;
import com.info.zhiduoduo.admin.model.formbean.crowdsource.AddressTaxRateFormBean;
import com.info.zhiduoduo.admin.model.formbean.crowdsource.SaveTaxRateFormBean;
import com.info.zhiduoduo.admin.model.formbean.invoice.ApprovalScreenshotFromBean;
import com.info.zhiduoduo.admin.model.formbean.invoice.EditRemarkFormBean;
import com.info.zhiduoduo.admin.model.formbean.maker.MakerListFormBean;
import com.info.zhiduoduo.admin.model.formbean.taxer.*;
import com.info.zhiduoduo.common.configs.CommonConfig;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.invoice.InvoiceType;
import com.info.zhiduoduo.common.constants.maker.MakerType;
import com.info.zhiduoduo.common.constants.project.ProjectType;
import com.info.zhiduoduo.common.excelconverter.ZddReadListener;
import com.info.zhiduoduo.common.exception.Asserts;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.formbean.BaseSimpleFormBean;
import com.info.zhiduoduo.common.utils.*;
import com.info.zhiduoduo.core.service.*;
import com.info.zhiduoduo.core.service.common.BaseService;
import com.info.zhiduoduo.core.service.wxmessage.WxTaxerWxMessageServiceImpl;
import com.info.zhiduoduo.repository.dto.maker.MakerDetailDto;
import com.info.zhiduoduo.repository.dto.maker.StudioBriefDto;
import com.info.zhiduoduo.repository.dto.maker.StudioDetailDto;
import com.info.zhiduoduo.repository.dto.taxer.TaxerCompanyListDto;
import com.info.zhiduoduo.repository.dto.taxer.TaxerInvoiceDto;
import com.info.zhiduoduo.repository.dto.taxer.TaxerInvoicesDto;
import com.info.zhiduoduo.repository.dto.taxer.TaxerPaymentDto;
import com.info.zhiduoduo.repository.entity.address.AddressTaxRate;
import com.info.zhiduoduo.repository.entity.company.CompanyAccount;
import com.info.zhiduoduo.repository.entity.crowdsource.CrowdsourceInvoice;
import com.info.zhiduoduo.repository.entity.crowdsource.CrowdsourceProject;
import com.info.zhiduoduo.repository.entity.crowdsource.CrowdsourceProjectItem;
import com.info.zhiduoduo.repository.entity.invoice.Invoice;
import com.info.zhiduoduo.repository.entity.invoice.InvoiceInventory;
import com.info.zhiduoduo.repository.entity.maker.Maker;
import com.info.zhiduoduo.repository.entity.maker.MakerAccount;
import com.info.zhiduoduo.repository.entity.maker.MakerStudio;
import com.info.zhiduoduo.repository.entity.recharge.RechargeRecord;
import com.info.zhiduoduo.repository.entity.system.BusinessManager;
import com.info.zhiduoduo.repository.entity.system.SystemManager;
import com.info.zhiduoduo.repository.entity.system.SystemProjectcategory;
import com.info.zhiduoduo.repository.entity.taxer.*;
import com.info.zhiduoduo.repository.mapper.maker.MakerAccountMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerStudioMapper;
import com.info.zhiduoduo.repository.mapper.taxer.TaxerCompanyMapper;
import com.info.zhiduoduo.repository.mapper.taxer.TaxerInviteCodeMapper;
import com.info.zhiduoduo.repository.mapper.taxer.TaxerInvoiceMapper;
import com.info.zhiduoduo.repository.mapper.taxer.TaxerPaymentMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.Positive;
import javax.validation.constraints.PositiveOrZero;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TaxerService extends BaseService {

	@Autowired
	WxTaxerWxMessageServiceImpl wxTaxerMessageService;
	@Autowired
	InvoiceInventoryService invoiceInventoryService;
	@Autowired
	CoreBrokerageService coreBrokerageService;
	@Autowired
	CoreTaxerService coreTaxerService;
	@Autowired
	CoreInvoiceService coreInvoiceService;
	@Autowired
	WxMessageService wxMessageService;
	@Autowired
	InvoiceService invoiceService;

	@Resource
	MakerMapper makerMapper;
	@Resource
	MakerAccountMapper makerAccountMapper;
	@Resource
	MakerStudioMapper makerStudioMapper;
	@Resource
	TaxerPaymentMapper taxerPaymentMapper;
	@Resource
	TaxerInvoiceMapper taxerInvoiceMapper;
	@Resource
	TaxerInviteCodeMapper taxerInviteCodeMapper;
	@Resource
	TaxerCompanyMapper taxerCompanyMapper;
	@Resource
	CoreSensitiveService coreSensitiveService;

	@Autowired
	CommonConfig commonConfig;

	public SmartResult<StudioBriefDto> taxerStudioExpireList(BaseSimpleFormBean<MakerListFormBean> formBean) {
		MakerListFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		String name = reqdata.getName();
		Date startDate = reqdata.getStartDate();
		Date endDate = reqdata.getEndDate();
		String bindcompname = reqdata.getBindcompname();
		Integer tradecategoryid = reqdata.getTradecategoryid();
		int taxAcctState = reqdata.getTaxAcctState();

		if (startDate == null) startDate = new Date(0);
		if (endDate == null) endDate = new Date();

		//失效日期：expire_date
		Page<StudioBriefDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		makerStudioMapper.getTaxerStudioList(taxAcctState, name, bindcompname, tradecategoryid, startDate, endDate);
		return smartResultPage(page);
	}

	@Transactional
	public SmartResult taxerStudioRenewal(BaseSimpleFormBean<TaxerStudioRenewalFormBean> formBean) {
		TaxerStudioRenewalFormBean reqdata = formBean.getReqdata();
		@Positive int userid = reqdata.getTaxerid();
		Maker maker = new Maker().selectById(userid);
		//获取创客姓名
		MakerAccount account = makerAccountMapper.getUserAccountByUserId(reqdata.getTaxerid());
		if (maker == null) return smartResult(StatusMsg.StatusMsg_701);

		//修改过期日期
		maker.setExpireDate(reqdata.getExpireDate()).updateById();
		//新增付款记录
		int type = Constants.TAXER_PAY_TYPE_RENEW;
		new TaxerPayment()
				.setUserid(userid)
				.setType(type)
				.setExpireDate(reqdata.getExpireDate())
				.setAmount(reqdata.getChargeAmount())
				.setState(2)//订单状态已付款
				.setManagerid(formBean.getUserid())
				.setRemark(reqdata.getRemark())
				.setVoucher(reqdata.getVoucher())
				.setConfirmtime(new Date())
				.insert();

		//新增收费记录
		new RechargeRecord().setRechargeTypeId(Constants.RECHARGE_GENERAL_TAXER_RENEWAL_FEE)
							.setRechargeAmount(reqdata.getChargeAmount())
							.setCustomerType(1)
							.setCustomerId(reqdata.getTaxerid())
							.setCustomerName(account.getRealname())
							.setRechargeRemark(reqdata.getRemark())
							.setRechargeVoucher(reqdata.getVoucher())
							.setCreatedBy(formBean.getUserid())
							.setRechargeTime(new Date())
							.insert();

		return smartResult();
	}

	public SmartResult createPayment(BaseSimpleFormBean<CreateTaxerPaymentFormBean> formBean) {
		@Valid CreateTaxerPaymentFormBean reqdata = formBean.getReqdata();

		@Positive int userid = reqdata.getUserid();
		MakerDetailDto maker = makerMapper.getUserDetail(userid);
		if (maker == null) return smartResult(StatusMsg.StatusMsg_701);

		int type = reqdata.getType();
		if (type == Constants.TAXER_PAY_TYPE_VERIFY) {
			//注册付费，检查状态
			if (maker.getRealnameAuth() != Constants.realname_auth_2) {
				return smartResult(StatusMsg.StatusMsg_709);
			}
		} else if (type == Constants.TAXER_PAY_TYPE_RENEW) {
			if (reqdata.getExpireDate() == null) {
				return smartResult(StatusMsg.StatusMsg_711);
			}

		} else if (type == Constants.TAXER_PAY_TYPE_INVOICE) {
			//发票税费，检查发票是否正常

		}
		TaxerPayment payment = new TaxerPayment();
		BeanUtils.copyProperties(reqdata, payment);
		if (payment.insert()) {
			return smartResult(payment.getPayid());
		}
		return optFailSmartResult();
	}

	public SmartResult<TaxerPaymentDto> getPaymentList(BaseSimpleFormBean<PaymentListFormBean> formBean) {
		@Valid PaymentListFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		String name = reqdata.getName();
		Date startDate = reqdata.getStartDate();
		Date endDate = reqdata.getEndDate();
		int state = reqdata.getState();
		int type = reqdata.getType();

		if (startDate == null) startDate = new Date(0);
		if (endDate == null) endDate = new Date();

		Page<TaxerPaymentDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		taxerPaymentMapper.getPaymentList(type, state, name, startDate, endDate);
		return smartResultPage(page);
	}

	/**
	 * 支付审核
	 */
	@Transactional
	public SmartResult confirmPayment(BaseSimpleFormBean<TaxerPaidVerifyFormBean> formBean) {
		@Valid TaxerPaidVerifyFormBean reqdata = formBean.getReqdata();
		int payid = reqdata.getPayid();
		String remark = reqdata.getRemark();
		String voucher = reqdata.getVoucher();
		int adminid = formBean.getUserid();
		SystemManager manager = new SystemManager().selectById(adminid);
		if (manager == null || manager.getState() != 1) return smartResult(StatusMsg.StatusMsg_128);

		TaxerPayment payment = new TaxerPayment().selectById(payid);
		if (payment == null) return smartResult(StatusMsg.StatusMsg_712);

		Integer userid = payment.getUserid();
		Integer type = payment.getType();
		if (payment.getState() == 2) return smartResult(StatusMsg.StatusMsg_713);

		Maker maker = new Maker().selectById(userid);
		//到期日期,默认为1年期限
		Date expireDate = reqdata.getExpireDate();
		if (expireDate == null) {
			expireDate = DateUtil.localDate2Date(LocalDate.now().minusDays(1).plusYears(1));
		}

		if (type == Constants.TAXER_PAY_TYPE_INVOICE) {
			//发票
			TaxerInvoice invoice = new TaxerInvoice().selectById(payment.getInvoiceid());
			if (invoice == null) return smartResult(StatusMsg.StatusMsg_714);
		}

		boolean update = payment.setState(2).setManagerid(adminid).setConfirmtime(new Date()).setRemark(remark).setVoucher(voucher).updateById();
		if (update) {
			Integer rechargeType = null;
			if (type == Constants.TAXER_PAY_TYPE_VERIFY) {//注册审核支付
				rechargeType = Constants.JAY_TAX_MAN_ACCOUNT_OPENING_FEE;
				maker.setExpireDate(expireDate);
				maker.updateById();
			} else if (type == Constants.TAXER_PAY_TYPE_RENEW) {//续期
				rechargeType = Constants.RECHARGE_GENERAL_TAXER_RENEWAL_FEE;

				maker.setExpireDate(expireDate);
				maker.updateById();
			} else if (type == Constants.TAXER_PAY_TYPE_INVOICE) {//发票税费
				rechargeType = Constants.RECHARGE_GENERAL_TAXER_RATE_FEE;
			}
			//收费类型=开户类型的就不查工作室名称
			String customerName = "";
			if (!rechargeType.equals(Constants.JAY_TAX_MAN_ACCOUNT_OPENING_FEE)) {
				MakerStudio studio = makerStudioMapper.getMakerStudio(userid);
				Asserts.notNull(studio, StatusMsg.StatusMsg_701);
				customerName = studio.getUsername();
			} else {
				MakerAccount account = makerAccountMapper.getUserAccountByUserId(userid);
				Asserts.notNull(account, StatusMsg.StatusMsg_111);
				customerName = account.getRealname();
			}
			//新增收费记录
			new RechargeRecord().setRechargeTypeId(rechargeType)
								.setRechargeAmount(payment.getAmount())
								.setCustomerType(1)
								.setCustomerId(payment.getUserid())
								.setCustomerName(customerName)
								.setRechargeRemark(remark)
								.setRechargeVoucher(voucher)
								.setCreatedBy(formBean.getUserid())
								.setRechargeTime(new Date())
								.insert();

			return smartResult();
		}

		return optFailSmartResult();
	}

	public SmartResult<TaxerInvoiceDto> getInvoiceList(BaseSimpleFormBean<TaxerInoviceListFormBean> formBean) {
		TaxerInoviceListFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		String name = reqdata.getName();
		Date startDate = reqdata.getStartDate();
		Date endDate = reqdata.getEndDate();
		Integer paidState = reqdata.getPaidState();
		int state = reqdata.getState();
		Integer invoiceType = reqdata.getInvoiceType();
		int userid = formBean.getUserid();
		SystemManager systemManager = new SystemManager().selectById(userid);
		if (null == systemManager || systemManager.getState() != 1) {
			return smartResult(StatusMsg.StatusMsg_128);
		}
		//操作人员对接城市
		String city = systemManager.getDockingCity();
		String dockingCity= "";
		if (StringUtil.isNotEmpty(city)) {
			dockingCity = " and ma.opening_location in ("+ city+") ";
		}

		if (startDate == null) startDate = new Date(0);
		if (endDate == null) endDate = new Date();

		Page<TaxerInvoiceDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<TaxerInvoiceDto> list = taxerInvoiceMapper.getInvoiceList(0, name, paidState, state, invoiceType, startDate, endDate,dockingCity);
		//获取企业策略性内容
		Set<Integer> userId =  new HashSet<>();
		for (TaxerInvoiceDto dto:list){
			userId.add(dto.getUserid());
		}
		Map<Integer,Integer> mapUser = invoiceService.getNoPolicyBilling(userId,1);
		Map<Integer,String> map = invoiceService.getSpecialNeedsContent(userId,1);
		Map<Integer,BigDecimal> bigDecimalMap = invoiceService.obtainQuarterlyAmount(userId);
		for (TaxerInvoiceDto dto:list){
			dto.setSpecialRequirementsContent(map.get(dto.getUserid()));
			dto.setQuarterlyAmount(bigDecimalMap.get(dto.getUserid()));
			if (mapUser.get(dto.getUserid()) == 1){
				dto.setIsApprovalScreenshot(1);
			}
		}
		return smartResultPage(page);
	}

	public void exportTaxerInvoiceList(HttpServletResponse response,TaxerInoviceListFormBean reqdata) {
		String name = reqdata.getName();
		Date startDate = reqdata.getStartDate();
		Date endDate = reqdata.getEndDate();
		Integer paidState = reqdata.getPaidState();
		int state = reqdata.getState();
		Integer invoiceType = reqdata.getInvoiceType();
		if (startDate == null) {
			startDate = new Date(0);
		}
		if (endDate == null) {
			endDate = new Date();
		}
		int managerid = reqdata.getManagerid();
		SystemManager systemManager = new SystemManager().selectById(managerid);
		if (null == systemManager || systemManager.getState() != 1) {
			LogUtil.error("导出 发票列表时 根据传入的操作人员managerid 查到的信息为空或信息被冻结！");
			return ;
		}
		//操作人员对接城市
		String city = systemManager.getDockingCity();
		String dockingCity= "";
		if (StringUtil.isNotEmpty(city)) {
			dockingCity = " and ma.opening_location in ("+ city+") ";
		}
		List<TaxerInvoiceDto> list = taxerInvoiceMapper.getInvoiceList(0, name, paidState, state, invoiceType, startDate, endDate, dockingCity);
		//如果是纯代理的创客，关联出 创客绑定的企业 对应的商务经理
		for (TaxerInvoiceDto taxerInvoiceDto : list) {
			if (1 == taxerInvoiceDto.getMakerType()) {
				Maker maker = new Maker().selectById(taxerInvoiceDto.getUserid());
				if (null == maker || null == maker.getBindcompid()) {
					LogUtil.error("导出 发票列表时 根据创客userid 未查到对应的创客信息或者创客未绑定企业！userid为：" + taxerInvoiceDto.getUserid());
					continue;
				}
				CompanyAccount companyAccount = new CompanyAccount().selectOne(Condition.create().eq("compid", maker.getBindcompid()));
				if (null == companyAccount) {
					LogUtil.error("导出 发票列表时 根据企业id 未查到对应的企业详细信息！企业id为：" + maker.getBindcompid());
					continue;
				}
				BusinessManager businessManager = new BusinessManager().selectById(companyAccount.getBusinessManagerId());
				if (null == businessManager) {
					LogUtil.error("导出 发票列表时 根据商务经理id 未查到对应的商务经理信息！企业id为：" + maker.getBindcompid() + "，商务经理id为：" + companyAccount.getBusinessManagerId());
					continue;
				}
				taxerInvoiceDto.setBusinessManager(businessManager.getBusinessManager());
			}
		}
		String file = RandomUtil.createRandomNo(" 发票", "");
		try {
			if (1 == reqdata.getAuth()) {
				EasyExcel.write(getExcelOutPutStream(response, file), TaxerInvoiceDto.class).sheet(" 发票").doWrite(list);
			}else {
				EasyExcel.write(getExcelOutPutStream(response, file), TaxerInvoicesDto.class).sheet(" 发票").doWrite(list);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public SmartResult editInovice(BaseSimpleFormBean<EditTaxerInvoiceFormBean> formBean) {
		EditTaxerInvoiceFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		TaxerInvoice invoice = new TaxerInvoice();
		BeanUtils.copyProperties(reqdata, invoice);

		//校验敏感词
		String checkResult = coreSensitiveService.checkSensitiveWords(invoice.getProjectname(), invoice.getProjectintro());
		Asserts.isBlank(checkResult, StatusMsg.StatusMsg_144);

		if (invoice.updateById()) return smartResult();
		return optFailSmartResult();
	}

	public SmartResult confirmInvoice(BaseSimpleFormBean<ConfirmTaxerInvoiceFormBean> formBean) {
		int managerid = formBean.getUserid();

		SystemManager manager = new SystemManager().selectById(managerid);
		if (manager == null) return errorParamSmartResult();

		@Valid ConfirmTaxerInvoiceFormBean reqdata = formBean.getReqdata();
		int invoiceid = reqdata.getInvoiceid();
		int taxCity = reqdata.getTaxCity();

		TaxerInvoice invoice = new TaxerInvoice().selectById(invoiceid);
		if (invoice == null) return smartResult(StatusMsg.StatusMsg_714);
		TaxerPayment taxerPayment = new TaxerPayment().selectById(invoice.getPayid());
		if (invoice.getState() == 2) return smartResult(StatusMsg.StatusMsg_715);
		if (taxerPayment.getState() != 2) return smartResult(StatusMsg.StatusMsg_716);

		InvoiceInventory inventory = new InvoiceInventory().selectById(invoice.getUserid());
		Asserts.notNull(inventory, StatusMsg.StatusMsg_220);

		boolean understock = false;
		Integer invoicetype = invoice.getInvoiceType();
		int hundredThousand = reqdata.getHundredThousand();
		int tenThousand = reqdata.getTenThousand();
		if (NumberUtil.equals(invoicetype, InvoiceType.GENERAL)) {
			understock = inventory.getGenHundredThousand() < hundredThousand || inventory.getGenTenThousand() < tenThousand;
		} else if (NumberUtil.equals(invoicetype, InvoiceType.SPECIAL)) {
			understock = inventory.getSpeHundredThousand() < hundredThousand || inventory.getSpeTenThousand() < tenThousand;
		}
		Asserts.notTrue(understock, StatusMsg.StatusMsg_220);

		boolean update = invoice.setTaxCity(taxCity).setManagerid(managerid).setConfirmtime(new Date()).setState(2).updateById();
		if (update) {

			invoiceInventoryService.recordInventoryOut(reqdata.getTenThousand(), reqdata.getHundredThousand(), invoice.getUserid(),
					invoice.getInvoiceType(), formBean.getUserid(),invoice.getInvoiceid(), ProjectType.TAXER);

			// 处理合伙人佣金
			coreBrokerageService.handleTaxerInvoicePartnerBrokerage(taxerPayment, invoice);

			// 通知
			StudioDetailDto studioDetail = makerStudioMapper.getStudioDetail(invoice.getUserid());
			Integer makerType = studioDetail.getMakerType();
			if (NumberUtil.equals(makerType, MakerType.TAXER)) {
				wxTaxerMessageService.sendTaxerInvoiceNotice(invoiceid);
//				wxTaxerMessageService.notifyMakerEvaluate(invoiceid);
			} else if (NumberUtil.equals(makerType, MakerType.INTELL)) {
//				wxMessageService.notifyMakerTaxerEvaluate(invoiceid);
				wxMessageService.sendTaxerInvoiceNotice(invoiceid);
			}
			return smartResult();
		}
		return optFailSmartResult();
	}

	public SmartResult editInvoiceRemark(BaseSimpleFormBean<EditTaxerInvoiceRemarkFormBean> formBean) {
		EditTaxerInvoiceRemarkFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		TaxerInvoice invoice = new TaxerInvoice().setInvoiceid(reqdata.getInvoiceid()).setRemark(reqdata.getRemark());

		if (invoice.updateById()) return smartResult();
		return optFailSmartResult();
	}

	public SmartResult getTaxerInviteCodeList(BaseSimpleFormBean<String> formBean) {
		@Valid String name = formBean.getReqdata();
		Page<Object> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		taxerInviteCodeMapper.selectListByName(name);
		return smartResultPage(page);
	}

	public SmartResult addEditInviteCode(BaseSimpleFormBean<AddEditInviteCodeFormBean> formBean) {
		@Valid AddEditInviteCodeFormBean reqdata = formBean.getReqdata();

		if (reqdata == null) return errorParamSmartResult();
		@PositiveOrZero int id = reqdata.getId();

		if (id == 0) {
			//新增
			TaxerInviteCode inviteCode = taxerInviteCodeMapper.selectByCode(reqdata.getInviteCode());
			if (inviteCode != null) return smartResult(StatusMsg.StatusMsg_721);
		}
		TaxerInviteCode inviteCode = new TaxerInviteCode();
		BeanUtils.copyProperties(reqdata, inviteCode);

		try {
			if (inviteCode.insertOrUpdate()) return smartResult(inviteCode.getId());
		} catch (Exception e) {
			LogUtil.error(ExceptionUtil.getErrorStackTrace(e));
		}
		return optFailSmartResult();
	}

	public SmartResult delInviteCode(BaseSimpleFormBean<Integer> formBean) {

		@Valid Integer id = formBean.getReqdata();

		boolean delete = new TaxerInviteCode().deleteById(id);
		if (delete) return smartResult();
		return optFailSmartResult();
	}

	public SmartResult saveInvoiceReceiptImg(BaseSimpleFormBean<ReceiptImgFormBean> formBean) {
		@Valid ReceiptImgFormBean reqdata = formBean.getReqdata();
		int invoiceid = reqdata.getInvoiceid();
		String receiptImg = reqdata.getReceiptImg();
		TaxerInvoice invoice = new TaxerInvoice().selectById(invoiceid);
		if (invoice == null) return errorParamSmartResult();

		invoice.setReceiptImg(receiptImg).updateById();
		return smartResult();
	}

	/**
	 *  获取 收藏的企业列表
	 * @param formBean
	 * @return
	 */
	public SmartResult<TaxerCompanyListDto> queryCompanyList(BaseSimpleFormBean<TaxerCompanyListFormBean> formBean) {
		TaxerCompanyListFormBean reqdata = formBean.getReqdata();
		String whereStr = "";
		if( reqdata != null ){
			if(  !StringUtil.isEmpty( reqdata.getName() ) ){
				whereStr += " and tc.company_name like '%"+reqdata.getName()+"%' ";
			}
			if( reqdata.getUserid() > 0 ){
				whereStr += " and tc.userid = "+reqdata.getUserid();
			}
		}

		Page<TaxerCompanyListDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<TaxerCompanyListDto> companyList = taxerCompanyMapper.queryCompanyList(whereStr);

		return smartResult(companyList, page.getTotal(), page.getPages(), page.getPageNum());
	}


	/**
	 * 导出 收藏的企业列表
	 */
	public void exportCollectTaxerCompanyList(HttpServletResponse response , TaxerCompanyListFormBean formBean){

		// TaxerCompanyListFormBean reqdata = formBean.getReqdata();
		String whereStr = "";
		if( formBean != null ){
			if( formBean.getUserid() > 0 ){
				whereStr += " and tc.userid = "+formBean.getUserid();
			}
			if(  !StringUtil.isEmpty( formBean.getName() ) ){
				whereStr += " and tc.company_name like '%"+formBean.getName()+"%' ";
			}
		}

		List<TaxerCompanyListDto> companyList = taxerCompanyMapper.queryCompanyList(whereStr);

		String file = RandomUtil.createRandomNo( " 企业列表", "");
		try {
			EasyExcel.write(getExcelOutPutStream(response, file), TaxerCompanyListDto.class).sheet(" 企业列表").doWrite(companyList);
		} catch (Exception e) {
			e.printStackTrace();
		}


	}

	public SmartResult importDealedProject(MultipartFile file, int userid, int type){
		if (0 == userid) {
			return errorParamSmartResult();
		}
		if (!file.isEmpty()) {
			List<ImportProjectTemplateFormBean> list = Lists.newArrayList();
			try {
				EasyExcel.read(file.getInputStream(), ImportProjectTemplateFormBean.class,
						new ZddReadListener<ImportProjectTemplateFormBean>() {
							@Override
							public void invoke(ImportProjectTemplateFormBean data, AnalysisContext context) {
								list.add(data);
							}
						}).sheet().doRead();
			} catch (IOException e) {
				log.error("导入已成交的 项目失败", e);
			}
			System.out.println("导入 历史项目：" + list.toString());
			List<MakerStudio> studioList = new ArrayList<>();
			// 检查创客是否都存在,如果不存在,不允许导入项目
			List<String> makerNotExistsList = list.stream().filter(fb -> {
				//查询工作室
				MakerStudio studio = new MakerStudio().selectOne(Condition.create().eq("username",fb.getName()));
				if (null == studio) {
					return true;
				} else {
					studioList.add(studio);
				}
				return false;
			}).map(ImportProjectTemplateFormBean::getName).collect(Collectors.toList());
			if (!CollectionUtils.isEmpty(makerNotExistsList)) {
				return SmartResult.fail(StatusMsg.StatusMsg_701).setList(makerNotExistsList);
			}
			// 检查创客是否开户
			List<String> makerNotOpenList = studioList.stream().filter(fb -> {
				if (2 != fb.getState()) {
					return true;
				}
				return false;
			}).map(MakerStudio::getUsername).collect(Collectors.toList());
			if (!CollectionUtils.isEmpty(makerNotOpenList)) {
				return SmartResult.fail(StatusMsg.StatusMsg_709).setList(makerNotOpenList);
			}
			//如果是纯代理，判断是否开通了 
			if (1 != type) {
				//判断创客类型，纯代理只能是 创客
				List<String> makerNotTypeList = studioList.stream().filter(fb -> {
					Maker maker = new Maker().selectById(fb.getUserid());
					if (1 == maker.getMakerType()) {
						return false;
					}
					return true;
				}).map(MakerStudio::getUsername).collect(Collectors.toList());
				if (!CollectionUtils.isEmpty(makerNotTypeList)) {
					return SmartResult.fail(StatusMsg.StatusMsg_804).setList(makerNotTypeList);
				}
				//判断是否开通了 
				List<String> makerNotOpeningList = studioList.stream().filter(fb -> {
					if (0 == fb.getTaxer()) {
						return true;
					}
					return false;
				}).map(MakerStudio::getUsername).collect(Collectors.toList());
				if (!CollectionUtils.isEmpty(makerNotOpeningList)) {
					return SmartResult.fail(StatusMsg.StatusMsg_710).setList(makerNotOpeningList);
				}
			} else {
				//判断创客类型， 只能是 创客
				List<String> makerNotTypeList = studioList.stream().filter(fb -> {
					Maker maker = new Maker().selectById(fb.getUserid());
					if (2 == maker.getMakerType()) {
						return false;
					}
					return true;
				}).map(MakerStudio::getUsername).collect(Collectors.toList());
				if (!CollectionUtils.isEmpty(makerNotTypeList)) {
					return SmartResult.fail(StatusMsg.StatusMsg_804).setList(makerNotTypeList);
				}
				//判断账户是否已经到期，如果到期则不能开票
				List<String> makerExpireList = studioList.stream().filter(fb -> {
					Maker maker = new Maker().selectById(fb.getUserid());
					if (null == maker.getExpireDate() || DateUtil.getStartOfDay(new Date()).after(maker.getExpireDate())) {
						return true;
					}
					return false;
				}).map(MakerStudio::getUsername).collect(Collectors.toList());
				if (!CollectionUtils.isEmpty(makerExpireList)) {
					return SmartResult.fail(StatusMsg.StatusMsg_720).setList(makerExpireList);
				}
			}
			if (null != list && list.size() > 0) {
				//循环添加
				list.forEach(bean -> {
					MakerStudio studio = new MakerStudio().selectOne(Condition.create().eq("username",bean.getName()));
					//查询企业在 收藏企业中是否存在
					TaxerCompany taxerCompany = new TaxerCompany().selectOne(Condition.create().eq("company_name",bean.getCompanyName()));
					//获取分类
					int categoryid = 0;
					if (StringUtil.isNotEmpty(bean.getCategoryname())) {
						SystemProjectcategory category = new SystemProjectcategory().selectOne(Condition.create().eq("projectcategory",bean.getCategoryname()));
						if (null != category) {
							categoryid = category.getProjectcategoryid();
						}
					}
					//收藏企业id
					int companyId;
					if (null == taxerCompany) {
						//新建企业
						TaxerCompany company = new TaxerCompany();
						company.setCompanyName(bean.getCompanyName())
								.setUserid(studio.getUserid())
								.setCreditcode(bean.getCompanyCreditcode())
								.setCompanyAddr(bean.getCompanyAddr())
								.setBankname(bean.getCompanyBank())
								.setAcctno(bean.getCompanyAcctno())
								.setCompanyPhone(bean.getCompanyPhone());
						company.insert();
						companyId = company.getCompanyid();
					} else {
						companyId = taxerCompany.getCompanyid();
					}
					//创建发票项目信息
					TaxerInvoiceProject project = new TaxerInvoiceProject();
					project.setUserid(studio.getUserid())
							.setProjectname(bean.getProjectName())
							.setCategoryid(categoryid)
							.setCategoryname(bean.getCategoryname())
							.setProjectcycle(bean.getProjectcycle())
							.setProjectintro(bean.getProjectDesc())
							.setInvoiceType(bean.getInvoiceType())
							.setInvoiceContent(bean.getInvoiceContent())
							.setProjectAmount(BigDecimal.valueOf(bean.getProjectAmount()))
							.setWhetherSupplement(1)
							.setCreatetime(bean.getCreatetime());
					project.insert();
					String applyno = RandomUtil.createRandomNo("IMP_BATCH_INVO_", "");
					TaxerInvoice invoice = new TaxerInvoice();
					invoice.setAmount(BigDecimal.valueOf(bean.getProjectAmount()))
							.setApplyno(applyno)
							.setInvoiceContent(bean.getInvoiceContent())
							.setInvoiceType(bean.getInvoiceType())
							.setUserid(studio.getUserid())
							.setUsername(studio.getUsername())
							.setStudioCreditcode(studio.getCreditcode())
							.setStudioPhone(studio.getStudiophone())
							.setStudioAddr(studio.getAddr())
							.setCompanyid(companyId)
							.setCompanyName(bean.getCompanyName())
							.setCompanyCreditcode(bean.getCompanyCreditcode())
							.setCompanyAddr(bean.getCompanyAddr())
							.setInvoiceEmail(bean.getInvoiceEmail())
							.setCompanyBank(bean.getCompanyBank())
							.setCompanyAcctno(bean.getCompanyAcctno())
							.setCompanyPhone(bean.getCompanyPhone())
							.setProjectid(project.getProjectid())
							.setProjectname(bean.getProjectName())
							.setCategoryid(categoryid)
							.setCategoryname(bean.getCategoryname())
							.setProjectcycle(bean.getProjectcycle())
							.setProjectintro(bean.getProjectDesc())
							.setCreatetime(bean.getCreatetime())
							.setConfirmtime(bean.getFinishtime())
							.setState(1)
							.setSupplementTime(new Date())
							.setWhetherSupplement(1)
							.setSupplementPersonnel(userid);
					if (invoice.insert()) {
						Maker maker = new Maker().selectById(studio.getUserid());
						//创建开票付款记录
						String payno = RandomUtil.createRandomNo("IMP_BATCH_TAX_", "");
						TaxerPayment payment = new TaxerPayment().setType(Constants.TAXER_PAY_TYPE_INVOICE)
								.setUserid(studio.getUserid())
								.setPayno(payno)
								.setInvoiceid(invoice.getInvoiceid())
								.setState(1)
								.setCreatetime(bean.getCreatetime())
								.setConfirmtime(bean.getCreatetime());
						payment.insert();
						// 初始化合伙人分佣记录
						coreBrokerageService.prepareProjectBrokerage(maker.getUserid(), studio.getUserid(), invoice.getInvoiceid(), ProjectType.TAXER);
						// 处理合伙人佣金
						coreBrokerageService.handleTaxerInvoicePartnerBrokerage(payment, invoice);
						// 计算发票税费
						coreTaxerService.calcInvoiceServiceChargeV2(invoice.getInvoiceid());
						// 更新发票和付款记录状态
						payment.setState(2).updateById();
						invoice.setState(2).setPayid(payment.getPayid()).updateById();
						//可以开税户
						if (studio.getTaxAcctState() == Constants.STUDIO_TAX_ACCT_NOT_QUALIFIED) {
							new MakerStudio().setUserid(studio.getUserid())
									.setTaxAcctState(Constants.STUDIO_TAX_ACCT_QUALIFIED)
									.setOpenTaxAcctStarttime(new Date())
									.updateById();
						}
					}
				});
			} else {
				return errorParamSmartResult();
			}
		}
		return smartResult();
	}

	public SmartResult deleteImportDealedProject(BaseSimpleFormBean<Object[]> formBean) {
		if (formBean == null || formBean.getReqdata() == null) {
			return errorParamSmartResult();
		}
		 Object[] projectIds = formBean.getReqdata();
		if(projectIds.length==0){
			return 	smartResult("请选择要删除的数据");
		}
		List<TaxerInvoiceProject> taxerInvoiceProjects = new TaxerInvoiceProject().selectList(Condition.create().in("projectid", projectIds));
		if(taxerInvoiceProjects.size()==0){
			return smartResult(StatusMsg.StatusMsg_301);
		}
		Iterator<TaxerInvoiceProject> iterator = taxerInvoiceProjects.iterator();
        while (iterator.hasNext()){
			TaxerInvoiceProject taxerInvoiceProject = iterator.next();
			if(taxerInvoiceProject.getWhetherSupplement()!=Constants.TRUE){
			return smartResult("不是补录数据不能删除");
		}
		if (!taxerInvoiceProject.deleteById()) {
			return smartResult(StatusMsg.StatusMsg_199);
		}
		TaxerInvoice taxerInvoice = new TaxerInvoice().selectOne(Condition.create().eq("projectid", taxerInvoiceProject.getProjectid()));
		if (taxerInvoice != null) {

			TaxerPayment invoiceid = new TaxerPayment().selectOne(Condition.create().eq("invoiceid", taxerInvoice.getInvoiceid()));
			if (!taxerInvoice.deleteById()) {
				return smartResult(StatusMsg.StatusMsg_199);
			}
			invoiceid.deleteById();
		}
        }
		return smartResult();

	}

	/**
	 * 根据地区id,档位数值添加档位
	 * */
	@Transactional
	public SmartResult insertAddressTaxRate(BaseSimpleFormBean<AddressTaxRateFormBean> formBean){
		if (null == formBean || null == formBean.getReqdata() || 0 == formBean.getUserid()){
			return errorParamSmartResult();
		}
		AddressTaxRateFormBean reqdata = formBean.getReqdata();
		//季度档位值
		int quarter = reqdata.getQuarter();
		//年度1档位值
		int yearOne = reqdata.getYearOne();
		//年度2档位值
		int yearTwo = reqdata.getYearTwo();
		//年度3档位值
		int yearThree = reqdata.getYearThree();
		if (0 == quarter || 0 == yearOne || 0 == yearTwo || 0 == yearThree) {
			return errorParamSmartResult();
		}

		AddressTaxRate addressTaxRate = new AddressTaxRate().selectOne(Condition.create().eq("addr_id",reqdata.getAddrid()));
		if (null == addressTaxRate) {
			addressTaxRate = new AddressTaxRate()
					.setAddrId(reqdata.getAddrid())
					.setQuarter(quarter)
					.setYearOne(reqdata.getYearOne())
					.setYearTwo(reqdata.getYearTwo())
					.setYearThree(reqdata.getYearThree())
					.setFounder(formBean.getUserid());
			if (!addressTaxRate.insert()) {
				return smartResult(StatusMsg.StatusMsg_199);
			}
		} else {
			addressTaxRate.setQuarter(quarter)
					.setYearOne(yearOne)
					.setYearTwo(yearTwo)
					.setYearThree(yearThree)
					.setUpdatetime(new Date());
			if (!addressTaxRate.updateById()) {
				return smartResult(StatusMsg.StatusMsg_199);
			}
		}
		return smartResult();
	}

	/**
	 * 根据城市id查询档位税率表
	 * */
	public SmartResult selectAddressTaxRate(BaseSimpleFormBean<Integer> formBean){
		if(null == formBean || null == formBean.getReqdata()){
			return errorParamSmartResult();
		}
		@Valid Integer addrId = formBean.getReqdata();
		AddressTaxRate addressTaxRate = new AddressTaxRate().selectOne(Condition.create().eq("addr_id",addrId));
		return smartResult(addressTaxRate);
	}

	/**
	 * 添加或修改创客费率
	 */
	@Transactional
	public SmartResult insertOrUpdateTaxRate(BaseSimpleFormBean<SaveTaxRateFormBean> formBean){
		if (null == formBean || null == formBean.getReqdata() || 0 == formBean.getUserid()) {
			return errorParamSmartResult();
		}
		SaveTaxRateFormBean bean = formBean.getReqdata();
		if (null == bean.getUserid() || 0 == bean.getUserid()) {
			return errorParamSmartResult();
		}
		Maker maker = new Maker().selectById(bean.getUserid());
		if (null == maker) {
			return smartResult(StatusMsg.StatusMsg_201);
		}
		TaxerRate taxerRate = new TaxerRate().selectOne(Condition.create().eq("userid",bean.getUserid()));
		if (null == taxerRate) {
			taxerRate = new TaxerRate()
					.setUserid(bean.getUserid())
					.setGearOne(new BigDecimal(bean.getGearOne()))
					.setGearTwo(new BigDecimal(bean.getGearTwo()))
					.setGearThree(new BigDecimal(bean.getGearThree()))
					.setGearFour(new BigDecimal(bean.getGearFour()))
					.setGearFive(new BigDecimal(bean.getGearFive()))
					.setFounder(formBean.getUserid());
			if (!taxerRate.insert()) {
				return smartResult(StatusMsg.StatusMsg_199);
			}
		} else {
			taxerRate.setGearOne(new BigDecimal(bean.getGearOne()))
					.setGearTwo(new BigDecimal(bean.getGearTwo()))
					.setGearThree(new BigDecimal(bean.getGearThree()))
					.setGearFour(new BigDecimal(bean.getGearFour()))
					.setGearFive(new BigDecimal(bean.getGearFive()))
					.setUpdatetime(new Date());
			if (!taxerRate.updateById()) {
				return smartResult(StatusMsg.StatusMsg_199);
			}
		}
		return smartResult();
	}

	/**
	 * 根据userid查询创客的费率
	 */
	public SmartResult selectTaxRateByList(BaseSimpleFormBean<Integer> formBean){
		if(null == formBean || null == formBean.getReqdata()){
			return errorParamSmartResult();
		}
		@Valid Integer userid = formBean.getReqdata();
		TaxerRate taxerRate = new TaxerRate().selectOne(Condition.create().eq("userid",userid));
		return smartResult(taxerRate);
	}

	public void fixSupplementProjectInvoice() {
		List<CrowdsourceProject> list = new CrowdsourceProject().selectList(Condition.create().isNotNull("supplement_time"));
		for (CrowdsourceProject project : list) {
			log.info("补录众包项目, projectid={}", project.getProjectid());
			Invoice invoice = new Invoice().selectOne(Condition.create().eq("projectid", project.getProjectid()).eq("project_type", 2));
			if (invoice == null) {
				// 没有发票, 需要补录
				// 补录发票
				log.info("没有发票, 需要补录, projectid={}", project.getProjectid());
				Date now = new Date();
				invoice = coreInvoiceService.createCrowdsourceProjectInvoice(project.getProjectid());
				invoice.setInvoicetype(StringUtil.toInt(project.getInvoiceType()))
						.setContent(project.getInvoiceContent())
						.setState(Constants.invoicestate_4)
						.setApplyTime(now)
						.setAccepttime(now)
						.setFinishtime(now)
						.setSupplementPersonnel(project.getSupplementPersonnel())
						.setSupplementTime(now)
						.setWhetherSupplement(Constants.TRUE);
				invoice.updateById();

				List<CrowdsourceProjectItem> itemList = new CrowdsourceProjectItem().selectList(
						Condition.create().eq("projectid", project.getProjectid()));
				for (CrowdsourceProjectItem projectItem : itemList) {
					// 补录成本发票
					CrowdsourceInvoice crowdsourceInvoice = coreInvoiceService.createCrowdsourceProjectMakerInvoice(
							projectItem.getId());
					// 成本发票是普票
					crowdsourceInvoice.setInvoiceType(String.valueOf(InvoiceType.GENERAL))
							.setGongQingInvoiceContent(project.getInvoiceContent())
							.setSupplementTime(new Date())
							.setSupplementPersonnel(project.getSupplementPersonnel())
							.setWhetherSupplement(Constants.TRUE);
					crowdsourceInvoice.updateById();
				}

			}
		}
	}


	public void fixOldServiceCharge2TaxFee() {
		Map<Integer, StudioDetailDto> makerMap = Maps.newHashMap();
		List<TaxerInvoice> list = new TaxerInvoice().selectAll();
		List<TaxerInvoice> totalChargeNotEqualList = Lists.newArrayList();
		List<TaxerInvoice> taxerServiceChargeTaxFeelList = Lists.newArrayList();
		for (TaxerInvoice invoice : list) {
			// 修复totalCharge
			BigDecimal serviceCharge = invoice.getServiceCharge();
			BigDecimal totalCharge = serviceCharge.add(invoice.getTaxFee());
			BigDecimal currTotalCharge = invoice.getTotalCharge();
			if (currTotalCharge.doubleValue() > 0 && !currTotalCharge.equals(totalCharge)) {
				totalChargeNotEqualList.add(invoice);
			} else {
				invoice.setTotalCharge(totalCharge);
			}
			// 修复以前的serviceCharge, 转到taxFee
			// 如果是 创客纯代理, 则服务费率和税率一直都是正确的.
			// 只需要修复 的发票. 因为以前的 只有服务费. 但是现在要把以前的服务费转移到税费上.费率也要转.
			Integer userid = invoice.getUserid();
			StudioDetailDto studio = makerMap.computeIfAbsent(userid, uid -> makerStudioMapper.getStudioDetail(uid));
			if (studio.getMakerType() == MakerType.TAXER) {
				if (NumberUtil.safeDouble(invoice.getPartnerProjectServiceRate()) == 0) {
					if (serviceCharge.doubleValue() > 0 && invoice.getTaxFee().doubleValue() == 0) {
						// 如果partnerProjectServiceRate = 0, 且当前的服务费有值, 则说明当前的这个服务费其实是税费. 需要转移过去.
						Double serviceRate = invoice.getServiceRate();
						invoice.setServiceCharge(BigDecimal.ZERO);
						invoice.setServiceRate(0d);
						invoice.setTaxFee(serviceCharge);
						invoice.setTaxRate(serviceRate);
					} else if (serviceCharge.doubleValue() > 0 && invoice.getTaxFee().doubleValue() > 0){
						// 如果这种情况下税费也有值呢invoice.getTaxFee() > 0, 理论上不存在这种情况. 记录下来.
						taxerServiceChargeTaxFeelList.add(invoice);
					}

				} else {
					// partnerProjectServiceRate > 0, 则说明存在合伙人分佣, 已经开始计算合伙人分佣了. 这时税费和服务费已经分开了. 不需要修复
				}
			}
			// 更新
			invoice.updateById();
		}
		if (!CollectionUtils.isEmpty(totalChargeNotEqualList)) {
			List<Integer> neList = totalChargeNotEqualList.stream().map(TaxerInvoice::getInvoiceid).collect(Collectors.toList());
			log.info("计算出来总服务费与当前已设置的服务费不一致的发票id: {}", neList);
		}
		if (!CollectionUtils.isEmpty(taxerServiceChargeTaxFeelList)) {
			List<Integer> neList = taxerServiceChargeTaxFeelList.stream().map(TaxerInvoice::getInvoiceid).collect(Collectors.toList());
			log.info(" 创客发票, 服务费和税费都有值的发票id: {}", neList);
		}
	}
	/**
	 *  发票编辑发票备注
	 */
	public SmartResult editRemark(BaseSimpleFormBean<EditRemarkFormBean> formBean) {
		EditRemarkFormBean reqdata = formBean.getReqdata();
		if(null == reqdata) return errorParamSmartResult();
		TaxerInvoice taxerInvoice = new TaxerInvoice().setInvoiceid(reqdata.getId()).setRemark(reqdata.getRemark());
		if (!taxerInvoice.updateById()) return optFailSmartResult();
		return smartResult();
	}


	/**
	 * 上传30万审批截图
	 * @param formBean
	 * @return
	 */
	public SmartResult approvalScreenshot(ApprovalScreenshotFromBean formBean) {
		for(Integer id:formBean.getInvoiceId()){
			TaxerInvoice invoice = taxerInvoiceMapper.selectById(id);
			if (null == invoice){
				continue;
			}
			invoice.setApprovalScreenshot(formBean.getApprovalScreenshot()).updateById();
		}
		return smartResult();
	}
}
